﻿// 功能：弹出表格式菜单
// 描述：
// 作者：温伟鹏
// 日期：2010/5/12 15:04:18

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
using MeizuSDK.Drawing;
using MeizuSDK.Core;

namespace MeizuSDK.Presentation
{
    /// <summary>
    /// 弹出表格式菜单
    /// </summary>
    public class GridMenu : Control
    {
        #region DllImport
        [DllImport("MZFCWrapper.dll")]
        private static extern IntPtr MzGridMenuCtor();

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzGridMenuSetPos(IntPtr pObj, int x, int y, int w, int h, uint flags);

        [DllImport("MZFCWrapper.dll")]
        private static extern int MzGridMenuCalcContentHeight(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool MzGridMenuAppendMenuItem(IntPtr pObj, int uIDNewItem, [MarshalAs(UnmanagedType.LPWStr)]string lpszItem, IntPtr pImage, IntPtr pImagePressed);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool MzGridMenuModifyMenuItem(IntPtr pObj, int uIDNewItem, [MarshalAs(UnmanagedType.LPWStr)] string lpszItem, IntPtr pImage, IntPtr pImagePressed);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool MzGridMenuEnableMenuItem(IntPtr pObj, int uIDItem, bool bEnabled);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool MzGridMenuRemoveAllMenuItem(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool MzGridMenuSetTextOnly(IntPtr pObj, bool bTextOnly);

        //[DllImport("MZFCWrapper.dll")]
        //private static extern bool MzGridMenuSetBorderLine(IntPtr pObj, uint uFlag);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool MzGridMenuIsContinue(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool MzGridMenuSetBGImage(IntPtr pObj, IntPtr hBitmap);

        //[DllImport("MZFCWrapper.dll")]
        //private static extern bool MzGridMenuGetBGRect(IntPtr pObj, ref RECT prcBG);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool MzGridMenuTrackGridMenuDialog(IntPtr pObj, IntPtr hWnd, int nBottomHeight, bool bEndSelect, int uAnimTypeShow, int uAnimTypeHide);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool MzGridMenuEndGridMenu(IntPtr pObj);
        #endregion

        #region 私有变量
        /// <summary>
        /// 菜单项集合
        /// </summary>
        private GridMenuItemCollection itemCollection;
        /// <summary>
        /// 菜单所属窗口指针
        /// </summary>
        private IntPtr hWnd;
        /// <summary>
        /// 锁屏消息
        /// </summary>
        private uint shellLockMsg;
        /// <summary>
        /// 菜单当前是否显示
        /// </summary>
        private bool isMenuContinue;
        #endregion

        #region 公共属性
        /// <summary>
        /// 获取或设置控件在容器中的位置
        /// </summary>
        public override Point Location
        {
            get
            {
                return base.Location;
            }
            set
            {
                MzGridMenuSetPos(Handle, value.X, value.Y, 0, 0, MzUser.SP_NOSIZE);
                //base.Location = value;
            }
        }
        /// <summary>
        /// 获取或设置控件位置的X坐标
        /// </summary>
        public override int X
        {
            get
            {
                return base.X;
            }
            set
            {
                //base.X = value;
                MzGridMenuSetPos(Handle, value, Y, 0, 0, MzUser.SP_NOSIZE);
            }
        }
        /// <summary>
        /// 获取或设置控件位置的Y坐标
        /// </summary>
        public override int Y
        {
            get
            {
                return base.Y;
            }
            set
            {
                //base.Y = value;
                MzGridMenuSetPos(Handle, X, value, 0, 0, MzUser.SP_NOSIZE);
            }
        }
        /// <summary>
        /// 获取或设置控件的大小
        /// </summary>
        public override Size Size
        {
            get
            {
                return base.Size;
            }
            set
            {
                //base.Size = value;
                MzGridMenuSetPos(Handle, 0, 0, value.Width, value.Height, MzUser.SP_NOMOVE);
            }
        }
        /// <summary>
        /// 获取或设置控件的宽度
        /// </summary>
        public override int Width
        {
            get
            {
                return base.Width;
            }
            set
            {
                //base.Width = value;
                MzGridMenuSetPos(Handle, 0, 0, value, Height, MzUser.SP_NOMOVE);
            }
        }
        /// <summary>
        /// 获取或设置控件的高度
        /// </summary>
        public override int Height
        {
            get
            {
                return base.Height;
            }
            set
            {
                //base.Height = value;
                MzGridMenuSetPos(Handle, 0, 0, Width, value, MzUser.SP_NOMOVE);
            }
        }
        /// <summary>
        /// 获取控件的客户端大小
        /// </summary>
        protected override int ContentHeight
        {
            get
            {
                return MzGridMenuCalcContentHeight(Handle);
            }
        }
        /// <summary>
        /// 获取菜单中的菜单项集合
        /// </summary>
        public GridMenuItemCollection Items
        {
            get
            {
                if (this.itemCollection == null)
                {
                    this.itemCollection = new GridMenuItemCollection(this);
                }
                return itemCollection;
            }
        }
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造弹出表格式菜单对象
        /// </summary>
        public GridMenu()
        {
            Handle = MzGridMenuCtor();
            SetID();
        }
        #endregion

        #region 函数

        #region 内部函数
        /// <summary>
        /// 向菜单中添加菜单项
        /// </summary>
        /// <param name="itemId">菜单项编号</param>
        /// <param name="text">菜单项文本</param>
        /// <param name="pImage">菜单项图标</param>
        /// <param name="pImagePressed">菜单项被按下时显示的图标</param>
        /// <returns>返回true表示添加成功；否则返回false</returns>
        internal bool AppendMenuItem(int itemId, string text, ImagingHelper pImage, ImagingHelper pImagePressed)
        {
            return MzGridMenuAppendMenuItem(Handle, itemId, text, (pImage == null ? IntPtr.Zero : pImage.Handle), (pImagePressed == null ? IntPtr.Zero : pImagePressed.Handle));
        }
        /// <summary>
        /// 修改指定索引的菜单项
        /// </summary>
        /// <param name="itemId">菜单项编号</param>
        /// <param name="text">菜单项文本</param>
        /// <param name="pImage">菜单项图标（IntPtr.Zero）</param>
        /// <param name="pImagePressed">菜单项被按下时显示的图标（IntPtr.Zero）</param>
        /// <returns>返回true表示修改成功；否则返回false</returns>
        internal bool ModifyMenuItem(int itemId, string text, ImagingHelper pImage, ImagingHelper pImagePressed)
        {
            //return MzGridMenuModifyMenuItem(Handle, itemId, text, pImage, pImagePressed);

            return MzGridMenuModifyMenuItem(Handle, itemId, text, (pImage == null ? IntPtr.Zero : pImage.Handle), (pImagePressed == null ? IntPtr.Zero : pImagePressed.Handle));
        }
        /// <summary>
        /// 启用/禁用指定索引的菜单项
        /// </summary>
        /// <param name="itemId">菜单项编号</param>
        /// <param name="enabled">true表示启用菜单项；false表示禁用菜单项</param>
        /// <returns>返回true，表示设置成功；否则返回false</returns>
        internal bool EnableMenuItem(int itemId, bool enabled)
        {
            return MzGridMenuEnableMenuItem(Handle, itemId, enabled);
        }
        /// <summary>
        /// 移除所有菜单项
        /// </summary>
        /// <returns></returns>
        internal bool RemoveAllItems()
        {
            return MzGridMenuRemoveAllMenuItem(Handle);
        }
        #endregion

        /// <summary>
        /// 设置菜单显示模式（仅文本、图像文本）
        /// </summary>
        /// <param name="textOnly">是否仅显示文本</param>
        public void SetMenuMode(bool textOnly)
        {
            MzGridMenuSetTextOnly(Handle, textOnly);
        }
        /// <summary>
        /// (窗口方法)判断弹出窗口是否在运行中
        /// </summary>
        /// <returns>返回true，表示正在运行；否则为false</returns>
        public bool IsContinue()
        {
            try
            {
                isMenuContinue = MzGridMenuIsContinue(Handle);
            }
            catch (Exception ex)
            {
                Console.Write(ex.Message);
            }

            return isMenuContinue;
        }
        /// <summary>
        /// (窗口方法)使用对话框方式弹出GridMenu，如果用户选择了其中一个菜单，则会发生MZ_WM_COMMAND消息给hWnd窗口。
        /// </summary>
        /// <param name="hWnd">弹出菜单的附属窗口句柄</param>
        /// <param name="bottomHeight">菜单距离屏幕底部的高度</param>
        /// <returns></returns>
        public bool Show(IntPtr hWnd, int bottomHeight)
        {
            return Show(hWnd, bottomHeight, true, AnimationType.None, AnimationType.None);
        }
        /// <summary>
        /// (窗口方法)使用对话框方式弹出GridMenu，如果用户选择了其中一个菜单，则会发生MZ_WM_COMMAND消息给hWnd窗口。
        /// </summary>
        /// <param name="hWnd">弹出菜单的附属窗口句柄</param>
        /// <param name="bottomHeight">菜单距离屏幕底部的高度</param>
        /// <param name="endSelect">是否选择完菜单项后</param>
        /// <param name="animTypeShow">菜单弹出动画类型</param>
        /// <param name="animTypeHide">菜单关闭动画类型</param>
        /// <returns></returns>
        public bool Show(IntPtr hWnd, int bottomHeight, bool endSelect, AnimationType animTypeShow, AnimationType animTypeHide)
        {
            this.isMenuContinue = true;
            this.hWnd = hWnd;
            // 注册锁屏消息
            ShellNotifyMsg.RegisterShellMessage(this.hWnd, ShellNotifyMsg.WM_MZSH_ENTRY_LOCKPHONE);
            // 获取锁屏消息
            shellLockMsg = ShellNotifyMsg.GetShellNotifyMsg_EntryLockPhone();

            bool result = MzGridMenuTrackGridMenuDialog(Handle, hWnd, bottomHeight, endSelect, (int)animTypeShow, (int)animTypeHide);

            return result;
        }
        /// <summary>
        /// 关闭菜单
        /// </summary>
        /// <returns></returns>
        public bool Close()
        {
            this.isMenuContinue = false;
            if (this.hWnd != IntPtr.Zero)
            {
                this.shellLockMsg = 0;
                ShellNotifyMsg.UnRegisterShellMessage(this.hWnd, ShellNotifyMsg.WM_MZSH_ENTRY_LOCKPHONE);
            }

            bool result = MzGridMenuEndGridMenu(Handle);
            return result;
        }
        /// <summary>
        /// 截获消息
        /// </summary>
        /// <param name="message"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        protected override void WndProc(uint message, uint wParam, uint lParam)
        {
            // 当锁屏或按下M键时，关闭菜单
            if (shellLockMsg == message || message == Application.HomeKeyMessage)
            {
                Close();
            }

            base.WndProc(message, wParam, lParam);
        }
        /// <summary>
        /// 销毁资源
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            // 自动关闭GridMenu
            //if (this.IsContinue())
            //    Close();
            base.Dispose(disposing);
        }
        #endregion
    }
}
